Recommit rL245802: Cleanup fancy pointer rebinding in list using __rebind_pointer. Currently we need an #ifdef branch every time we use pointer traits to rebind a pointer because it is done differently in C++11 and C++03. This patch introduces the __rebind_pointer utility to clean this up. Also add a test that list and it's iterators can be instantiated with incomplete element types. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@245806 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/list b/include/list index 14201a8..28d5055 100644 --- a/include/list +++ b/include/list 
@@ -191,19 +191,10 @@  template <class _Tp, class _VoidPtr>  struct __list_node_base  { - typedef typename pointer_traits<_VoidPtr>::template -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES - rebind<__list_node<_Tp, _VoidPtr> > pointer; -#else - rebind<__list_node<_Tp, _VoidPtr> >::other pointer; -#endif - - typedef typename pointer_traits<_VoidPtr>::template -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES - rebind<__list_node_base> __base_pointer; -#else - rebind<__list_node_base>::other __base_pointer; -#endif + typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type + pointer; + typedef typename __rebind_pointer<_VoidPtr, __list_node_base>::type + __base_pointer;    pointer __prev_;  pointer __next_; @@ -232,12 +223,8 @@  template <class _Tp, class _VoidPtr>  class _LIBCPP_TYPE_VIS_ONLY __list_iterator  { - typedef typename pointer_traits<_VoidPtr>::template -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES - rebind<__list_node<_Tp, _VoidPtr> > __node_pointer; -#else - rebind<__list_node<_Tp, _VoidPtr> >::other __node_pointer; -#endif + typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type + __node_pointer;    __node_pointer __ptr_;   @@ -262,13 +249,7 @@  typedef bidirectional_iterator_tag iterator_category;  typedef _Tp value_type;  typedef value_type& reference; - typedef typename pointer_traits<_VoidPtr>::template -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES - rebind<value_type> -#else - rebind<value_type>::other -#endif - pointer; + typedef typename __rebind_pointer<_VoidPtr, value_type>::type pointer;  typedef typename pointer_traits<pointer>::difference_type difference_type;    _LIBCPP_INLINE_VISIBILITY @@ -365,12 +346,8 @@  template <class _Tp, class _VoidPtr>  class _LIBCPP_TYPE_VIS_ONLY __list_const_iterator  { - typedef typename pointer_traits<_VoidPtr>::template -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES - rebind<__list_node<_Tp, _VoidPtr> > __node_pointer; -#else - rebind<__list_node<_Tp, _VoidPtr> >::other __node_pointer; -#endif + typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type + __node_pointer;    __node_pointer __ptr_;   @@ -392,13 +369,7 @@  typedef bidirectional_iterator_tag iterator_category;  typedef _Tp value_type;  typedef const value_type& reference; - typedef typename pointer_traits<_VoidPtr>::template -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES - rebind<const value_type> -#else - rebind<const value_type>::other -#endif - pointer; + typedef typename __rebind_pointer<_VoidPtr, const value_type>::type pointer;  typedef typename pointer_traits<pointer>::difference_type difference_type;    _LIBCPP_INLINE_VISIBILITY 
diff --git a/include/memory b/include/memory index 38ce433..9d214be 100644 --- a/include/memory +++ b/include/memory 
@@ -932,6 +932,15 @@  {return _VSTD::addressof(__r);}  };   +template <class _From, class _To> +struct __rebind_pointer { +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + typedef typename pointer_traits<_From>::template rebind<_To> type; +#else + typedef typename pointer_traits<_From>::template rebind<_To>::other type; +#endif +}; +  // allocator_traits    namespace __has_pointer_type_imp 
diff --git a/test/std/containers/sequences/list/incomplete_type.pass.cpp b/test/std/containers/sequences/list/incomplete_type.pass.cpp new file mode 100644 index 0000000..adfb4d4 --- /dev/null +++ b/test/std/containers/sequences/list/incomplete_type.pass.cpp 
@@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <list> + +// Check that std::list and it's iterators can be instantiated with an incomplete +// type. + +#include <list> + +struct A { + std::list<A> l; + std::list<A>::iterator it; + std::list<A>::const_iterator cit; + std::list<A>::reverse_iterator rit; + std::list<A>::const_reverse_iterator crit; +}; + +int main() { + A a; +}